package cascade.components
{
	import mx.containers.Panel;
	import mx.core.Application;
	import mx.core.UIComponent;
	import flash.utils.*;
	import mx.controls.TextInput;
	import mx.core.UITextField;
	import mx.events.FlexEvent;
	import mx.containers.ControlBar;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.KeyboardEvent;
	import flash.display.DisplayObject;
	import mx.core.IUIComponent;
	import mx.core.EdgeMetrics;
	import mx.core.FlexVersion;
	
	
	[Event("editBegin")]
	[Event("editDone")]
	[Event("edited")]
	
	public class EditablePanel extends Panel
	{
		protected var input:TextInput;
		protected var buttonBar:UIComponent;
		
		public function EditablePanel() {
			addEventListener(FlexEvent.CREATION_COMPLETE, init);
		}
		
		private function init(event:FlexEvent):void {
			titleTextField.addEventListener(MouseEvent.CLICK, editTitle);
			titleBar.addEventListener(Event.RESIZE, onResize);
		}
		
		private function editTitle(event:MouseEvent):void {
			if (input || event.localX > titleBar.width)
				return;
			input = new TextInput();
			input.x = titleTextField.x - 2;
			input.y = titleTextField.y - 2;
			input.width = titleTextField.width + 4;
			input.height = titleTextField.height + 4;
			input.text = title;
			input.styleName = titleTextField.styleName;
			titleBar.addChild(input);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEditDone);
			input.addEventListener(KeyboardEvent.KEY_DOWN, keyEditDone);
			input.setFocus();
			input.focusManager.hideFocus();
			input.setSelection(0, input.text.length);
			dispatchEvent(new Event("editBegin"));
		}
		
		private function onResize(event:Event = null):void {
			if (input)
				input.width = titleBar.width;
		}
		
		private function mouseEditDone(event:MouseEvent):void {
			var dObj:DisplayObject = event.target as DisplayObject;
			while (dObj) {
				if (dObj == input)
					return;
				dObj = dObj.parent;
			}
			
			var edited:Boolean = false;
			if (title != input.text) {
				title = input.text;
				edited = true;
			}
			removeInput();
			dispatchEvent(new Event("editDone"));
			if (edited)
				dispatchEvent(new Event("edited"));
			
		}
		
		private function keyEditDone(event:KeyboardEvent):void {
			if (event.charCode == 27) { //esc, discard edit
				removeInput();
				dispatchEvent(new Event("editDone"));
			} else if (event.charCode == 13) { //enter, save edit
				removeInput();
				var edited:Boolean = false;
				if (title != input.text) {
					title = input.text;
					edited = true;
				}
				dispatchEvent(new Event("editDone"));
				if (edited)
					dispatchEvent(new Event("edited"));
			}
		}
		
		private function removeInput():void {
			stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseEditDone);
			input.removeEventListener(KeyboardEvent.KEY_DOWN, keyEditDone);
			input.focusManager.hideFocus();
			callLater(function():void {
				titleBar.removeChild(input);
				input = null;
			});
		}
		
		protected override function layoutChrome(unscaledWidth:Number, unscaledHeight:Number):void {
			super.layoutChrome(unscaledWidth, unscaledHeight);
			
			if (buttonBar) {
				buttonBar.setActualSize(buttonBar.measuredWidth, buttonBar.measuredHeight);
				buttonBar.move(unscaledWidth - buttonBar.width - getStyle("paddingRight"), 0);
				titleTextField.setActualSize(titleTextField.width - buttonBar.width, titleTextField.height);
			}
		}
		
		public override function createComponentsFromDescriptors(recurse:Boolean=true):void {
			super.createComponentsFromDescriptors();
			
			if (numChildren != 0) {
				var firstChild:IUIComponent = IUIComponent(getChildAt(0));
				
				if (firstChild is ControlBar) {
					
					var oldChildDocument:Object = firstChild.document;
					
					removeChild(DisplayObject(firstChild));
					firstChild.document = oldChildDocument;
					rawChildren.addChild(DisplayObject(firstChild));
					buttonBar = firstChild as UIComponent;
					callLater(bringButtonBarToTop);
				}
			}
		}
		
		protected function bringButtonBarToTop():void {
			rawChildren.addChild(buttonBar);
		}
		
		protected override function commitProperties():void {
			super.commitProperties();
			titleTextField.text = titleTextField.text || "(no title set)";
			if (initialized)
            	layoutChrome(unscaledWidth, unscaledHeight);
		}
		
		protected override function getHeaderHeight():Number {
			var headerHeight:Number = super.getHeaderHeight();
			
			if (buttonBar && buttonBar.includeInLayout) {
				headerHeight = Math.max(headerHeight, buttonBar.height);
			}
			
			return headerHeight;
		}
	}
}